package kzhang.dbtest.hibernate.basic;

import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import org.slf4j.*;

public class TestExample {

    final static Logger logger = LoggerFactory.getLogger(TestExample.class);

    /**
     * @param args
     */
    public static void main(String[] args) {
        // logger.setLevel(Level.INFO);
        try {
            Honey forestHoney = new Honey();
            forestHoney.setName("forest honey");
            forestHoney.setTaste("very sweet");
            Honey countryHoney = new Honey();
            countryHoney.setName("country honey");
            countryHoney.setTaste("tasty");
            createHoney(forestHoney);
            createHoney(countryHoney);
            // our instances have a primary key now:
            logger.info("{}", forestHoney);
            logger.info("{}", countryHoney);
            listHoney();
            deleteHoney(countryHoney);
            listHoney();
            forestHoney.setName("Norther Forest Honey");
            updateHoney(forestHoney);
    
            // test delete by id
            logger.info("==== test delete by id ====");
            Honey zjw = new Honey();
            zjw.setName("Kevin");
            zjw.setTaste("Zhang");
            createHoney(zjw);
            listHoney();
            logger.info("{}", zjw);
            logger.info("zjw id is " + zjw.getId().toString());
            deleteHoneyByID(zjw.getId().intValue());
            listHoney();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private static void listHoney() {
        Transaction tx = null;
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try {
            tx = session.beginTransaction();
            List honeys = session.createQuery("select h from Honey as h")
                    .list();
            for (Iterator iter = honeys.iterator(); iter.hasNext();) {
                Honey element = (Honey) iter.next();
                //logger.debug("{}", element);
            }
            tx.commit();
        } catch (RuntimeException e) {
            if (tx != null && tx.isActive()) {
                try {
                    // Second try catch as the rollback could fail as well
                    tx.rollback();
                } catch (HibernateException e1) {
                    logger.debug("Error rolling back transaction");
                }
                // throw again the first exception
                throw e;
            }

        }
    }

    private static void deleteHoney(Honey honey) {
        Transaction tx = null;
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try {
            tx = session.beginTransaction();
            session.delete(honey);
            tx.commit();
        } catch (RuntimeException e) {
            if (tx != null && tx.isActive()) {
                try {
                    // Second try catch as the rollback could fail as well
                    tx.rollback();
                } catch (HibernateException e1) {
                    logger.debug("Error rolling back transaction");
                }
                // throw again the first exception
                throw e;
            }
        }
    }

    private static void deleteHoneyByID(int id) {
        logger.debug("try to delete Honey id = " + id);
        Transaction tx = null;
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try {
            tx = session.beginTransaction();
            session.delete("kzhang.dbtest.hibernate.basic.Honey", new Integer(id));
            tx.commit();
        } catch (RuntimeException e) {
            if (tx != null && tx.isActive()) {
                try {
                    // Second try catch as the rollback could fail as well
                    tx.rollback();
                } catch (HibernateException e1) {
                    logger.debug("Error rolling back transaction");
                }
                // throw again the first exception
                throw e;
            }
        }
    }

    private static void createHoney(Honey honey) {
        Transaction tx = null;
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try {
            tx = session.beginTransaction();
            session.save(honey);
            tx.commit();
        } catch (RuntimeException e) {
            if (tx != null && tx.isActive()) {
                try {
                    // Second try catch as the rollback could fail as well
                    tx.rollback();
                } catch (HibernateException e1) {
                    logger.debug("Error rolling back transaction");
                }
                // throw again the first exception
                throw e;
            }
        }
    }

    private static void updateHoney(Honey honey) {
        Transaction tx = null;
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try {
            tx = session.beginTransaction();
            session.update(honey);
            tx.commit();
        } catch (RuntimeException e) {
            if (tx != null && tx.isActive()) {
                try {
                    // Second try catch as the rollback could fail as well
                    tx.rollback();
                } catch (HibernateException e1) {
                    logger.debug("Error rolling back transaction");
                }
                // throw again the first exception
                throw e;
            }
        }
    }
}
